package org.jeecg.modules.online.cgform.controller;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.OnlineAuth;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.*;
import org.jeecg.modules.online.cgform.components.LinkDown;
import org.jeecg.modules.online.cgform.converter.ConvertUtil;
import org.jeecg.modules.online.cgform.entity.OnlCgformEnhanceJs;
import org.jeecg.modules.online.cgform.entity.OnlCgformField;
import org.jeecg.modules.online.cgform.entity.OnlCgformHead;
import org.jeecg.modules.online.cgform.model.OnlCgformModel;
import org.jeecg.modules.online.cgform.model.OnlComplexModel;
import org.jeecg.modules.online.cgform.model.OnlGenerateModel;
import org.jeecg.modules.online.cgform.model.TreeModel;
import org.jeecg.modules.online.cgform.service.IOnlCgformFieldService;
import org.jeecg.modules.online.cgform.service.IOnlCgformHeadService;
import org.jeecg.modules.online.cgform.service.IOnlCgformSqlService;
import org.jeecg.modules.online.cgform.service.IOnlineService;
import org.jeecg.modules.online.cgform.util.CgFormExcelHandler;
import org.jeecg.modules.online.cgform.util.CgformUtil;
import org.jeecg.modules.online.cgform.util.EnhanceJsUtil;
import org.jeecg.modules.online.cgform.util.GenerateCodeFileToZip;
import org.jeecg.modules.online.config.exception.BusinessException;
import org.jeecg.modules.online.config.exception.DBException;
import org.jeecg.modules.online.config.util.DbTableUtil;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.PostgreSQLSequenceMaxValueIncrementer;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.*;
import java.net.URLDecoder;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Title: Controller
 * @Description: Online表单开发
 * @Author: jeecg-boot
 * @Date: 2019-03-12
 * @Version: V1.0
 */
@Slf4j
@RestController("olApiController")
@RequestMapping("/ol/cgform/api")
public class OlApiController {

	@Autowired
	private IOnlCgformHeadService onlCgformHeadService;

	@Autowired
	private IOnlCgformFieldService onlCgformFieldService;

	@Autowired
	private IOnlCgformSqlService onlCgformSqlService;

	@Autowired
	private ISysBaseAPI sysBaseAPI;

    @Autowired
    private IOnlineService onlineService;

	@Value("${jeecg.path.upload}")
	private String upLoadPath;

	@Value(value="${jeecg.uploadType}")
	private String uploadType;

	@PostMapping(value = "/addAll")
	public Result<?> addAll(@RequestBody OnlCgformModel model) {
		try {
			String tbname = model.getHead().getTableName();
			if(DbTableUtil.judgeTableIsExit(tbname)) {
				return Result.error("数据库表["+tbname+"]已存在,请从数据库导入表单");
			}
			return onlCgformHeadService.addAll(model);
		} catch (Exception e) {
			log.error("OnlCgformApiController.addAll()发生异常：" + e.getMessage(),e);
			return Result.error("操作失败");
		}
	}

	@PutMapping(value = "/editAll")
	public Result<?> editAll(@RequestBody OnlCgformModel model) {
		try {
			return onlCgformHeadService.editAll(model);
		} catch (Exception e) {
			log.error("OnlCgformApiController.editAll()发生异常：" + e.getMessage(),e);
			return Result.error("操作失败");
		}
	}


	/**
	 * 查询columns 和 数据字典
	 * @param code
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@OnlineAuth("getColumns")
	@GetMapping(value = "/getColumns/{code}")
	public Result<OnlComplexModel> getColumns(@PathVariable("code") String code) {
		Result<OnlComplexModel> result = new Result<OnlComplexModel>();
		OnlCgformHead head = onlCgformHeadService.getById(code);
		if (head == null) {
			result.error500("实体不存在");
			return result;
		}
        OnlComplexModel model = this.onlineService.queryOnlineConfig(head);
        result.setResult(model);
		return result;
	}

	/**
	 * 查询列表分页数据
	 * @param code
	 * @param request
	 * @return
	 */
	@PermissionData
	@OnlineAuth("getData")
	@GetMapping(value = "/getData/{code}")
	public Result<Map<String,Object>> getData(@PathVariable("code") String code,HttpServletRequest request) {
		Result<Map<String,Object>> result = new Result<>();
		OnlCgformHead head = onlCgformHeadService.getById(code);
		if (head == null) {
			result.error500("实体不存在");
			return result;
		}
		try {
			String tbname = head.getTableName();
			Map<String,Object> params = CgformUtil.getParameterMap(request);
			Map<String,Object> page = onlCgformFieldService.queryAutolistPage(tbname, code, params,null);
			dataReprocessing(head,page);
			result.setResult(page);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			result.error500("数据库查询失败，"+e.getMessage());
		}
		return result;
	}

	/**
	 * 查询表单结构数据
	 * @param code
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@OnlineAuth("getFormItem")
	@GetMapping(value = "/getFormItem/{code}")
	public Result<?> getFormItem(@PathVariable("code") String code,HttpServletRequest request) {
		OnlCgformHead head = this.onlCgformHeadService.getById(code);
		if(head==null) {
			Result.error("表不存在");
		}
		Result<JSONObject> result = new Result<>();
		OnlCgformEnhanceJs onlCgformEnhanceJs = this.onlCgformHeadService.queryEnhanceJs(code, CgformUtil.ENHANCE_FORM);
		JSONObject obj = this.onlineService.queryOnlineFormObj(head,onlCgformEnhanceJs);
		//log.info("----动态表单获取JSON-SCHEMA>>"+schema.toJSONString());
		if(head.getTableType()==2) {
			//主表 则需要写一下schema
			JSONObject schema = obj.getJSONObject("schema");
			String subStr = head.getSubTableStr();
			if(oConvertUtils.isNotEmpty(subStr)) {
				List<OnlCgformHead> subHeadList = new ArrayList<OnlCgformHead>();
				for (String tbname : subStr.split(",")) {
					OnlCgformHead tempTable = this.onlCgformHeadService.getOne(new LambdaQueryWrapper<OnlCgformHead>().eq(OnlCgformHead::getTableName, tbname));
					if(tempTable==null) {
						continue;
					}
					subHeadList.add(tempTable);
				}
				if(subHeadList.size()>0){
					//排序逻辑
					Collections.sort(subHeadList, new Comparator<OnlCgformHead>() {
						@Override
                        public int compare(OnlCgformHead o1, OnlCgformHead o2) {
                            Integer o1OrderNum = o1.getTabOrderNum();
                            if (o1OrderNum == null) {
                                o1OrderNum = 0;
                            }
                            Integer o2OrderNum = o2.getTabOrderNum();
                            if (o2OrderNum == null) {
                                o2OrderNum = 0;
                            }
                            return o1OrderNum.compareTo(o2OrderNum);
                        }
					});

					for (OnlCgformHead tempTable : subHeadList) {
						//查询子表字段
						List<OnlCgformField> subFieldList = this.onlCgformFieldService.queryAvailableFields(tempTable.getId(), tempTable.getTableName(),null, false);
						//处理JS增强
						//update-begin-author:taoyan date:20200212 for:TASK #3235 【严重】Online表单JS增强使用了ES6语法，IE不兼容
						EnhanceJsUtil.overwriteJsSub(onlCgformEnhanceJs, tempTable.getTableName(), subFieldList);
						//update-end-author:taoyan date:20200212 for:TASK #3235 【严重】Online表单JS增强使用了ES6语法，IE不兼容
						JSONObject subJson = new JSONObject();
						//查询被禁用字段
						List<String> subDisabledFieldNameList = this.onlCgformFieldService.queryDisabledFields(tempTable.getTableName());

						if(1==tempTable.getRelationType()) {
							//one to one
							subJson = CgformUtil.getJsonSchemaByCgformFieldList(subFieldList,subDisabledFieldNameList,null);
						}else {
							//one to many
							subJson.put("columns",  CgformUtil.getJEditableTableColumnsJson(subFieldList,subDisabledFieldNameList));
						}
                        subJson.put("id", tempTable.getId());
						//subJson.put("columns",  CgformUtil.getJEditableTableColumnsJson(subFieldList));
						subJson.put("describe", tempTable.getTableTxt());
						subJson.put("key", tempTable.getTableName());
						subJson.put("view", "tab");
						subJson.put("order",tempTable.getTabOrderNum());//增加排序字段标识子表顺序
						subJson.put("relationType", tempTable.getRelationType());
						schema.getJSONObject("properties").put(tempTable.getTableName(), subJson);
					}
				}
			}

			//JS增强
			if(onlCgformEnhanceJs!=null && oConvertUtils.isNotEmpty(onlCgformEnhanceJs.getCgJs())) {
				obj.put("enhanceJs", EnhanceJsUtil.theLastString(onlCgformEnhanceJs.getCgJs()));
			}
		}
		result.setResult(obj);
		return result;
	}

	/**
	 * 根据表名拿到表的配置信息
	 * @param table
	 * @return
	 */
	@GetMapping(value = "/getFormItemBytbname/{table}")
	public Result<?> getFormItemBytbname(@PathVariable("table") String table,@RequestParam(name = "taskId", required = false) String taskId) {
		Result<JSONObject> result = new Result<>();
		LambdaQueryWrapper<OnlCgformHead> query = new LambdaQueryWrapper<OnlCgformHead>();
		query.eq(OnlCgformHead::getTableName,table);
		OnlCgformHead head = this.onlCgformHeadService.getOne(query);
		if(head==null) {
			Result.error("表不存在");
		}
		JSONObject obj = new JSONObject();
		//流程需要配置权限
		head.setTaskId(taskId);
		obj.put("schema", onlCgformHeadService.queryFormItem(head));
		obj.put("head", head);
		result.setResult(obj);
		return result;
	}

	@OnlineAuth("getEnhanceJs")
	@GetMapping(value = "/getEnhanceJs/{code}")
	public Result<?> getEnhanceJs(@PathVariable("code") String code,HttpServletRequest request) {
		String enhanceJsStr = "";
		OnlCgformEnhanceJs enhanceJs = this.onlCgformHeadService.queryEnhanceJs(code, "form");
		if(enhanceJs!=null && oConvertUtils.isNotEmpty(enhanceJs.getCgJs())) {
			//update-begin-author:taoyan date:20200212 for:TASK #3235 【严重】Online表单JS增强使用了ES6语法，IE不兼容
			enhanceJsStr = EnhanceJsUtil.overFinalWriteJs(enhanceJs.getCgJs(), null);
			//update-end-author:taoyan date:20200212 for:TASK #3235 【严重】Online表单JS增强使用了ES6语法，IE不兼容
		}
		return Result.ok(enhanceJsStr);
	}

	/**
	  * 查询表单数据
	 * @param code
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/form/{code}/{id}")
	public Result<?> getFormData(@PathVariable("code") String code,@PathVariable("id") String id) {
		try {
			Map<String, Object> map = this.onlCgformHeadService.queryManyFormData(code, id);
			return Result.ok(CgformUtil.transLowerCaseMapKey(map));
		} catch (Exception e) {
			log.error("Online表单查询异常：" + e.getMessage(),e);
			return Result.error("查询失败，"+e.getMessage());
		}
	}

	/**
	  * 查询子表表单数据
	 * @param table
	 * @param mainId
	 * @return
	 */
	@GetMapping(value = "/subform/{table}/{mainId}")
	public Result<?> getSubFormData(@PathVariable("table") String table,@PathVariable("mainId") String mainId) {
		try {
			Map<String, Object> map = this.onlCgformHeadService.querySubFormData(table, mainId);
			return Result.ok(CgformUtil.transLowerCaseMapKey(map));
		} catch (Exception e) {
			log.error("Online表单查询异常：" + e.getMessage(),e);
			return Result.error("查询失败，"+e.getMessage());
		}
	}


	/**
	  * 查询子表表单数据
	 * @param table
	 * @param mainId
	 * @return
	 */
	@GetMapping(value = "/subform/list/{table}/{mainId}")
	public Result<?> getSubFormDataList(@PathVariable("table") String table,@PathVariable("mainId") String mainId) {
		try {
			return Result.ok(this.onlCgformHeadService.queryManySubFormData(table, mainId));
		} catch (Exception e) {
			log.error("Online表单查询异常：" + e.getMessage(),e);
			return Result.error("查询失败，"+e.getMessage());
		}
	}

	/**
	 * 根据 tableName 查询表单数据
	 *
	 * @param tableName
	 *            online表单的 tableName
	 * @param dataId
	 *            数据表的id
	 * @return
	 */
	@GetMapping(value = "/form/table_name/{tableName}/{dataId}")
	public Result<?> getFormDataByTableName(@PathVariable("tableName") String tableName, @PathVariable("dataId") String dataId) {
		try {
			// 根据tableName查询出online的Id
			LambdaQueryWrapper<OnlCgformHead> queryWrapper = new LambdaQueryWrapper<OnlCgformHead>();
			queryWrapper.eq(OnlCgformHead::getTableName, tableName);
			OnlCgformHead head = this.onlCgformHeadService.getOne(queryWrapper);
			if (head == null) {
				throw new Exception("OnlCgform tableName: " + tableName + " 不存在！");
			}
			return this.getFormData(head.getId(), dataId);
		} catch (Exception e) {
			log.error("Online表单查询异常，" + e.getMessage(), e);
			return Result.error("查询失败，"+ e.getMessage());
		}
	}

	/**
	 * 表单新增
	 * @param code
	 * @param jsonObject
	 * @return
	 */
	@OnlineAuth("form")
	@PostMapping(value = "/form/{code}")
	public Result<String> formAdd(@PathVariable("code") String code,@RequestBody JSONObject jsonObject,HttpServletRequest request) {
		Result<String> result = new Result<String>();
		try {
			String id = CgformUtil.randomId();
			jsonObject.put("id",id);
			String xAccessToken = TokenUtils.getTokenByRequest(request);
			this.onlCgformHeadService.saveManyFormData(code,jsonObject,xAccessToken);
			result.setSuccess(true);
			result.setResult(id);
		} catch (Exception e) {
			log.error("OnlCgformApiController.formAdd()发生异常：",e);
			result.setSuccess(false);
			result.setMessage("保存失败，"+ CgformUtil.getOnlineErrorMsg(e));
		}
		return result;
	}

	/**
	 * 表单修改
	 * @param code
	 * @param jsonObject
	 * @return
	 */
	@OnlineAuth("form")
	@PutMapping(value="/form/{code}")
	public Result<?> formEdit(@PathVariable("code") String code,@RequestBody JSONObject jsonObject) {
		try {
			this.onlCgformHeadService.editManyFormData(code,jsonObject);
		} catch (Exception e) {
			log.error("OnlCgformApiController.formEdit()发生异常：" + e.getMessage(),e);
			return Result.error("修改失败，"+ CgformUtil.getOnlineErrorMsg(e));
		}
		return Result.ok("修改成功！");
	}

	/**
	 * 列表删除
	 * @param code
	 * @param id
	 * @return
	 */
	@OnlineAuth("form")
	@DeleteMapping(value="/form/{code}/{id}")
	public Result<?> formDelete(@PathVariable("code") String code,@PathVariable("id") String id) {
		try {
			if(id.indexOf(",")>0) {
				//批量删除
				OnlCgformHead head = onlCgformHeadService.getById(code);
				if (head == null) {
					return Result.error("实体不存在");
				}
				if(head.getTableType()==2){
					onlCgformFieldService.deleteAutoListMainAndSub(head, id);
				}else{
					String tbname = head.getTableName();
					onlCgformFieldService.deleteAutoListById(tbname, id);
				}
			}else {
				//删除一条记录 走增强逻辑 批量删除没走增强逻辑
				this.onlCgformHeadService.deleteOneTableInfo(code, id);
			}
		} catch (Exception e) {
			log.error("OnlCgformApiController.formEdit()发生异常：" + e.getMessage(),e);
			return Result.error("删除失败");
		}
		return Result.ok("删除成功!");
	}

	/**
	 * 列表删除
	 *
	 * @param code
	 * @param id
	 * @return
	 */
	@DeleteMapping(value = "/formByCode/{code}/{id}")
	public Result<?> deleteDataByCode(@PathVariable("code") String code, @PathVariable("id") String id) {
		try {
			//批量删除
			OnlCgformHead head = onlCgformHeadService.getOne(new LambdaQueryWrapper<OnlCgformHead>().eq(OnlCgformHead::getTableName, code));
			if (head == null) {
				return Result.error("实体不存在");
			}
			if (id.indexOf(",") > 0) {
				//批量删除
				String tbname = head.getTableName();
				onlCgformFieldService.deleteAutoListById(tbname, id);
			} else {
				//删除一条记录 走增强逻辑 批量删除没走增强逻辑
				this.onlCgformHeadService.deleteOneTableInfo(head.getId(), id);
			}
		} catch (Exception e) {
			log.error("OnlCgformApiController.formEdit()发生异常：" + e.getMessage(), e);
			return Result.error("删除失败");
		}
		return Result.ok("删除成功!");
	}

	/**
	 * 获取查询条件
	 */
	@OnlineAuth("getQueryInfo")
	@GetMapping(value = "/getQueryInfo/{code}")
	public Result<?> getQueryInfo(@PathVariable("code") String code) {
	    try {
	    	List<Map<String,String>> list = onlCgformFieldService.getAutoListQueryInfo(code);
			return Result.ok(list);
		} catch (Exception e) {
			log.error("OnlCgformApiController.getQueryInfo()发生异常：" + e.getMessage(),e);
			return Result.error("查询失败");
		}
	}

	/**
	 * 同步数据库
	 */
	@PostMapping(value = "/doDbSynch/{code}/{synMethod}")
	public Result<?> doDbSynch(@PathVariable("code") String code,@PathVariable("synMethod") String synMethod) {
		try {
			long starttime = System.currentTimeMillis();
			onlCgformHeadService.doDbSynch(code, synMethod);
			log.info("==同步数据库消耗时间"+ (System.currentTimeMillis()-starttime)+"毫秒");
		} catch (Exception e) {
			log.error(e.getMessage(),e);
			return Result.error("同步数据库失败，"+ CgformUtil.getOnlineErrorMsg(e));
		}
		return Result.ok("同步数据库成功!");
	}


	/**
	  * 导出
	 * @param code
	 * @param request
	 * @param response
	 */
	@SuppressWarnings("unchecked")
	@OnlineAuth("exportXls")
	@PermissionData
	@GetMapping(value = "/exportXls/{code}")
	public void exportXls(@PathVariable("code") String code,HttpServletRequest request, HttpServletResponse response) {
		//1.查表信息
		OnlCgformHead head = onlCgformHeadService.getById(code);
		if (head == null) {
			return;
		}
		String sheetName = head.getTableTxt();
		//2.获取查询条件
		String paramsStr = request.getParameter("paramsStr");
		Map<String,Object> params = new HashMap<>();
		String deString = null;
		if (oConvertUtils.isNotEmpty(paramsStr)) {
			try {
				deString = URLDecoder.decode(paramsStr, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				log.error(e.getMessage(), e);
			}
			if(deString!=null) {
				params = JSONObject.parseObject(deString,Map.class);
			}
		}
		//设置为此值则查询所有数据
		params.put("pageSize",-521);
		Map<String,Object> pageData = this.onlCgformFieldService.queryAutolistPage(head.getTableName(),head.getId(),params,null);
		List<OnlCgformField> fieldList = (List<OnlCgformField>)pageData.get("fieldList");
		List<Map<String,Object>> data = (List<Map<String,Object>>)pageData.get("records");
		List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
		//5.根据selections 判断过滤数据
		String selections = params.get("selections")==null?null:params.get("selections").toString();
		if(oConvertUtils.isNotEmpty(selections)) {
			List<String> selectionList = Arrays.asList(selections.split(","));
			result = data.stream().filter(item -> selectionList.contains(item.get("id"))).collect(Collectors.toList());
		}else {
			if(data==null){
				data = new ArrayList<Map<String,Object>>();
			}
			result.addAll(data);
		}
		// 转换器转换
		ConvertUtil.doConvertDataList(ConvertUtil.out,result,fieldList);
		//update-begin-author:taoyan date:20200218 for:java增强导出
		try {
			onlCgformHeadService.executeEnhanceExport(head,result);
		} catch (BusinessException e) {
			log.error("导出java增强处理出错",e.getMessage());
		}
		//update-end-author:taoyan date:20200218 for:java增强导出

		//6.封装导出列对应title实体
		List<ExcelExportEntity> entityList = convertToExportEntity(fieldList,"id");

		//7.处理子表
		if (head.getTableType()==2) {
			//只有当 erp风格时候 exportSingleOnly = 1
			if(oConvertUtils.isEmpty(params.get(CgformUtil.ONL_EXPORT_ARG))){
				String subTableStr = head.getSubTableStr();
				if (oConvertUtils.isNotEmpty(subTableStr)) {
					String[] subTables = subTableStr.split(",");
					for (String subTable : subTables) {
						addAllSubTableDate(subTable, params, result, entityList);
					}
				}
			}
		}

		//8.导出workbook
		Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(null, sheetName), entityList, result);
		//9.response写出
		OutputStream outputStream=null;
		try {
			response.setContentType("application/x-msdownload;charset=utf-8");

			String browse = BrowserUtils.checkBrowse(request);
			String codedFileName = head.getTableTxt()+"-v"+head.getTableVersion();
			if ("MSIE".equalsIgnoreCase(browse.substring(0, 4))) {
				response.setHeader("content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(codedFileName, "UTF-8") + ".xls");
			} else {
				String newtitle = new String(codedFileName.getBytes("UTF-8"), "ISO8859-1");
				response.setHeader("content-disposition", "attachment;filename=" + newtitle + ".xls");
			}

			OutputStream out=response.getOutputStream();
			workbook.write(out);
	        response.flushBuffer();
		} catch (Exception e) {
			log.error("--通过流的方式获取文件异常--"+e.getMessage(),e);
		}finally{
			if(outputStream!=null){
				try {
					outputStream.close();
				} catch (IOException e) {
					log.error(e.getMessage(), e);
				}
			}
		}
	}

	@OnlineAuth("importXls")
	@PostMapping(value = "/importXls/{code}")
	public Result<?> importXls(@PathVariable("code") String code,HttpServletRequest request, HttpServletResponse response) {
		long start = System.currentTimeMillis();
		Result<?> result = new Result<>();
		String message = "";
		try {
			//1.查表信息
			OnlCgformHead head = onlCgformHeadService.getById(code);
			if (head == null) {
				return Result.error("数据库不存在该表记录");
			}
			//2.获取查询列
			LambdaQueryWrapper<OnlCgformField> query = new LambdaQueryWrapper<OnlCgformField>();
			query.eq(OnlCgformField::getCgformHeadId, code);
			List<OnlCgformField> fieldList = this.onlCgformFieldService.list(query);
			String importSingleOnly = request.getParameter(CgformUtil.ONL_IMPORT_ARG);
			//update-begin-author:taoyan date:20200311 for:online 一对多，子表的图片导入不成功
			List<String> imgList = CgformUtil.getImageColumnList(fieldList);
			if(oConvertUtils.isEmpty(importSingleOnly) && head.getTableType()==2 && oConvertUtils.isNotEmpty(head.getSubTableStr())) {
				for (String tbname: head.getSubTableStr().split(",")) {
					OnlCgformHead subTable = onlCgformHeadService.getOne(new LambdaQueryWrapper<OnlCgformHead>().eq(OnlCgformHead::getTableName, tbname));
					if(subTable==null) {
						continue;
					}
					List<OnlCgformField> subFiledList = this.onlCgformFieldService.list(new LambdaQueryWrapper<OnlCgformField>().eq(OnlCgformField::getCgformHeadId, subTable.getId()));
					List<String> subImgList = CgformUtil.getSubImageColumnList(subFiledList,subTable.getTableTxt());
					if(subImgList.size()>0){
						imgList.addAll(subImgList);
					}
				}
			}
			//update-end-author:taoyan date:20200311 for:online 一对多，子表的图片导入不成功
			JSONObject foreignKeysJson = null;
			String foreignKeys = request.getParameter(CgformUtil.ONL_IMPORT_FOREIGNKEYS);
			if(oConvertUtils.isNotEmpty(foreignKeys)){
				foreignKeysJson = JSONObject.parseObject(foreignKeys);
			}
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();

			DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
			String databaseType = DbTableUtil.getDatabaseType(dataSource);
			for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
				MultipartFile file = entity.getValue();// 获取上传文件对象
				ImportParams params = new ImportParams();
				params.setImageList(imgList);//设置图片列集合
				params.setDataHanlder(new CgFormExcelHandler(fieldList,upLoadPath,uploadType));
				List<Map<String, Object>> importExcelDataList = ExcelImportUtil.importExcel(file.getInputStream(),  Map.class, params);
				if (importExcelDataList == null) {
					message = "识别模版数据错误";
					log.error(message);
				} else {
					Object mainId = "";
					List<Map<String, Object>> mainDataList = new ArrayList<Map<String, Object>>();
					for (int i = 0; i < importExcelDataList.size(); i++) {
						Map<String, Object> map=importExcelDataList.get(i);
						//标志是否为主表数据
						boolean isMainData = false;
						Set<String> keySet = map.keySet();
						Map<String,Object> mainData = new HashMap<String,Object>();
						mainData.put("hs",i+2+"");
						for (String key : keySet) {
							if (key.indexOf("$subTable$")==-1) {
								if (key.indexOf("$mainTable$")!=-1 && oConvertUtils.isNotEmpty(map.get(key).toString())) {
									isMainData = true;
									//TMD 注意：不要在循环里获取connection或是dataSource相关的信息 因为那样直接就莫名其妙的不报错然后跑不了
									mainId = getPkValue(head,dataSource,databaseType);
								}
								mainData.put(key.replace("$mainTable$", ""), map.get(key));
							}
						}
						if (isMainData) {
							//处理字典项 TODO 这一块太浪费效率
						    //dealDicForImport(mainData, fieldList);
							mainData.put("id", mainId);//主表数据
							//String jsonStr = JSON.toJSONString(mainData);
							//this.onlCgformFieldService.saveFormData(fieldList, head.getTableName(),JSONObject.parseObject(jsonStr));
							mainDataList.add(mainData);
							mainId =  mainData.get("id");
						}
						//如果excel中没有设置值 则 此处应该用前端传过来的外键值
						if(foreignKeysJson!=null){
							for(String key:foreignKeysJson.keySet()){
								System.out.println(key+"="+foreignKeysJson.getString(key));
								mainData.put(key,foreignKeysJson.getString(key));
							}
						}
						map.put("$mainTable$id", mainId);//为子表准备
					}
					if(mainDataList==null || mainDataList.size() ==0){
						result.setSuccess(false);
						result.setMessage("导入失败，匹配的数据条数为零!");
						return result;
					}
					//更新pid及haschild
					for (int i = 0; i < mainDataList.size(); i++) {
						Map aMap=  mainDataList.get(i);
						aMap.put("has_child","0");
						for (int j = 0; j < mainDataList.size(); j++) {
							Map bMap=  mainDataList.get(j);
							if(bMap.get("prows").equals(aMap.get("hs"))){
								bMap.put("pid",aMap.get("id"));
								aMap.put("has_child","1");
							}
						}
					}
					this.onlCgformSqlService.saveBatchOnlineTable(head, fieldList, mainDataList);


					//导入子表数据，如果有
					if(oConvertUtils.isEmpty(importSingleOnly) && head.getTableType()==2 && oConvertUtils.isNotEmpty(head.getSubTableStr())) {
						for (String tbname: head.getSubTableStr().split(",")) {

							OnlCgformHead subTable = onlCgformHeadService.getOne(new LambdaQueryWrapper<OnlCgformHead>().eq(OnlCgformHead::getTableName, tbname));
							if(subTable==null) {
								continue;
							}
							LambdaQueryWrapper<OnlCgformField> subFieldQuery = new LambdaQueryWrapper<OnlCgformField>();
							subFieldQuery.eq(OnlCgformField::getCgformHeadId, subTable.getId());
							List<OnlCgformField> subFiledList = this.onlCgformFieldService.list(subFieldQuery);
							List<Map<String, Object>> subDataList = new ArrayList<Map<String, Object>>();

							//将表头字段替换成数据库中对应的字段名
							String configName = subTable.getTableTxt();
							for (Map<String, Object> map : importExcelDataList) {
								//标志是否为子表数据
								boolean isSubData = false;
								Map subData = new HashMap();
								for (OnlCgformField fieldEntity: subFiledList) {
									//外键主表名
									String mainTab = fieldEntity.getMainTable();
									//外键主键字段
									String mainField = fieldEntity.getMainField();
									boolean isForeignKey = head.getTableName().equals(mainTab) && oConvertUtils.isNotEmpty(mainField);
									String tempKey = configName+"_"+fieldEntity.getDbFieldTxt();
									//已经考虑兼容多个外键的情况
									if(isForeignKey){
										subData.put(fieldEntity.getDbFieldName(), map.get("$mainTable$"+mainField));
									}
									Object subObj = map.get("$subTable$"+tempKey);
									if (null != subObj && oConvertUtils.isNotEmpty(subObj.toString())) {
										isSubData = true;
										subData.put(fieldEntity.getDbFieldName(), subObj);
									}
								}
								//设置子表记录ID
								if (isSubData) {
									//处理字典项
									//dealDicForImport(subData, subFiledList);
									subData.put("id", getPkValue(subTable,dataSource,databaseType));
									subDataList.add(subData);
									//String subDataJsonStr = JSON.toJSONString(subData);
									//this.onlCgformSqlService.saveOrUpdateSubData(subDataJsonStr,subTable,subFiledList);
								}
							}
							if(subDataList.size()>0){
								this.onlCgformSqlService.saveBatchOnlineTable(subTable, subFiledList, subDataList);
							}

						}
					}
					message = "文件导入成功！";
				}
			}
			result.setSuccess(true);
			result.setMessage("导入成功!");
		} catch (Exception e) {
			result.setSuccess(false);
			result.setMessage(e.getMessage());
			log.error(e.getMessage(), e);
		}
		/*
		 * 288条数据 saveBatchOnlineTable-2943毫秒
		 * 288条数据 循环中插入-2323毫秒 3016毫秒 2127毫秒
		 *
		 * 1152条数据 saveBatchOnlineTable-8523毫秒
		 * 1152条数据 循环中插入-8875毫秒
		 *
		 * 4608条数据 saveBatchOnlineTable-29717毫秒=====
		 * 4608条数据 循环中插入-32809毫秒
		 *
		 * 看不出太大差别
		 *
		 * 1w条数据 saveBatchOnlineTable-57612毫秒=====并没有传说中的那么卡吧
		 *
		 * 优化TODO :
		 * 3.本次测试列比较简单，要是列复杂会更慢
		 * 1.字典的替换
		 * 2.每次插入都会拼一个sql,这其实也很浪费，
		 * 但是问题在于每条数据因为某一列不存在值导致他的SQL可能不一致,所以必须每次都重新拼接,
		 * 可以搞个strict模式, 在该模式下，保证数据基本一致，字符串的不存在的默认设置空,时间/数值必须赋值 ，这样只需要设置一条sql。每次传入不同数据即可
		 */
		log.info("=====online导入数据完成,耗时:"+(System.currentTimeMillis()-start)+"毫秒=====");
		return result;
	}

	/**
	 * 自定义按钮请求方法
	 * @return
	 */
	@PostMapping(value = "/doButton")
	public Result<?> doButton(@RequestBody JSONObject json) {
		String formId = json.getString("formId");
		String dataId = json.getString("dataId");
		String buttonCode = json.getString("buttonCode");
		//获取当前页面上的表单数据json
		JSONObject uiFormData = json.getJSONObject("uiFormData");
		try {
			this.onlCgformHeadService.executeCustomerButton(buttonCode, formId, dataId);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return Result.error("执行失败!");
		}
		return Result.ok("执行成功!");
	}


	/**
	 * 获取主键值
	 * @param cghead
	 * @param dataSource
	 * @param dbType
	 * @return
	 * @throws SQLException
	 * @throws DBException
	 */
	public Object getPkValue(OnlCgformHead cghead, DataSource dataSource, String dbType) throws SQLException, DBException {
		Object pkValue = null;
		String pkType = cghead.getIdType();
		String pkSequence = cghead.getIdSequence();
		if(oConvertUtils.isNotEmpty(pkType)&&"UUID".equalsIgnoreCase(pkType)){
			pkValue = CgformUtil.randomId();
		}else if(oConvertUtils.isNotEmpty(pkType)&&"NATIVE".equalsIgnoreCase(pkType)){
			if(oConvertUtils.isNotEmpty(dbType)&&"oracle".equalsIgnoreCase(dbType)){
				OracleSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(dataSource, "HIBERNATE_SEQUENCE");
				try{
					pkValue = incr.nextLongValue();
				}catch (Exception e) {
					log.error(e.getMessage(), e);
				}
			}else if(oConvertUtils.isNotEmpty(dbType)&&"postgres".equalsIgnoreCase(dbType)){
				PostgreSQLSequenceMaxValueIncrementer incr = new PostgreSQLSequenceMaxValueIncrementer(dataSource, "HIBERNATE_SEQUENCE");
				try{
					pkValue = incr.nextLongValue();
				}catch (Exception e) {
					log.error(e.getMessage(), e);
				}
			}else{
				pkValue = null;
			}
		}else if(oConvertUtils.isNotEmpty(pkType)&&"SEQUENCE".equalsIgnoreCase(pkType)){
			if(oConvertUtils.isNotEmpty(dbType)&&"oracle".equalsIgnoreCase(dbType)){
				OracleSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(dataSource, pkSequence);
				try{
					pkValue = incr.nextLongValue();
				}catch (Exception e) {
					log.error(e.getMessage(), e);
				}
			}else if(oConvertUtils.isNotEmpty(dbType)&&"postgres".equalsIgnoreCase(dbType)){
				PostgreSQLSequenceMaxValueIncrementer incr = new PostgreSQLSequenceMaxValueIncrementer(dataSource, pkSequence);
				try{
					pkValue = incr.nextLongValue();
				}catch (Exception e) {
					log.error(e.getMessage(), e);
				}
			}else{
				pkValue = null;
			}
		}else{
			pkValue = CgformUtil.randomId();
		}
		return pkValue;
	}

	/**
	 * 导入字典值转换
	 * @param result
	 * @param beans
	 */
	private void dealDicForImport(Map result,List<OnlCgformField> beans) {
		for (OnlCgformField bean : beans) {
			String dicTable = bean.getDictTable();//字典Table
			String dicCode = bean.getDictField();//字典Code
			String dicText = bean.getDictText();//字典text
			if (oConvertUtils.isEmpty(dicTable) && oConvertUtils.isEmpty(dicCode)) {
				//不需要处理字典
				continue;
			} else {
				if (!"popup".equals(bean.getFieldShowType())) {
					List<DictModel> dicDataList;
					String value = String.valueOf(result.get(bean.getDbFieldName()));
					if(oConvertUtils.isEmpty(dicTable)) {
						dicDataList = this.sysBaseAPI.queryDictItemsByCode(dicCode);
					}else {
						dicDataList = this.sysBaseAPI.queryTableDictItemsByCode(dicTable, dicText, dicCode);
					}
					for (DictModel item : dicDataList) {
						if(value.equals(item.getText())) {
							result.put(bean.getDbFieldName(), item.getValue());
						}
					}
				}
			}
		}
	}

	/**
	 * 获取导出实体配置 支持字典转换
	 * @param lists
	 * @param pkField
	 * @return
	 */
	private List<ExcelExportEntity> convertToExportEntity(List<OnlCgformField> lists,String pkField) {
		List<ExcelExportEntity> entityList = new ArrayList<ExcelExportEntity>();
		for (int i = 0; i < lists.size(); i++) {
			if(null!=pkField && pkField.equals(lists.get(i).getDbFieldName())) {
				continue;
			}
			if (lists.get(i).getIsShowList()==1) {
				String fieldName = lists.get(i).getDbFieldName();
				ExcelExportEntity entity = new ExcelExportEntity(lists.get(i).getDbFieldTxt(),fieldName);
				if("image".equals(lists.get(i).getFieldShowType())){
					entity.setType(2);
					entity.setExportImageType(3);
					entity.setImageBasePath(upLoadPath);
					entity.setHeight(50);
					entity.setWidth(60);
				}else{
					int columnWidth = lists.get(i).getDbLength() == 0 ? 12 : lists.get(i).getDbLength() > 30 ? 30 : lists.get(i).getDbLength();
					if (lists.get(i).getFieldShowType().equals("date")) {
						entity.setFormat("yyyy-MM-dd");
					} else if (lists.get(i).getFieldShowType().equals("datetime")) {
						entity.setFormat("yyyy-MM-dd HH:mm:ss");
					}
					if(columnWidth<10){
						columnWidth = 10;
					}
					entity.setWidth(columnWidth);
				}
				//字典值设置
				/*String dictCode = lists.get(i).getDictField();
				if (oConvertUtils.isNotEmpty(dictCode)) {
					List<String> dictReplaces = new ArrayList<String>();
					List<DictModel> dictList = sysBaseAPI.queryDictItemsByCode(dictCode);
					for (DictModel d : dictList) {
						dictReplaces.add(d.getText() + "_" + d.getValue());
					}
					//男_1, 女_2
					entity.setReplace(dictReplaces.toArray(new String[dictReplaces.size()]));
				}*/
				entityList.add(entity);
			}
		}
		return entityList;
	}

	/**
	 * 把从表数据加到主表中
	 *
	 * @param params
	 * @param result
	 * @param entityList
	 */
	@SuppressWarnings("unchecked")
	private void addAllSubTableDate(String subTable,Map<String, Object> params, List<Map<String, Object>> result, List<ExcelExportEntity> entityList) {
		OnlCgformHead head = onlCgformHeadService.getOne(new LambdaQueryWrapper<OnlCgformHead>().eq(OnlCgformHead::getTableName, subTable));
		LambdaQueryWrapper<OnlCgformField> query = new LambdaQueryWrapper<OnlCgformField>();
		query.eq(OnlCgformField::getCgformHeadId, head.getId());
		query.orderByAsc(OnlCgformField::getOrderNum);
		List<OnlCgformField> fieldList = this.onlCgformFieldService.list(query);
		String mainField = "",linkField="";
		for (OnlCgformField onlCgformField : fieldList) {
			if(oConvertUtils.isNotEmpty(onlCgformField.getMainField())) {
				mainField = onlCgformField.getMainField();
				linkField = onlCgformField.getDbFieldName();
				break;
			}
		}
		ExcelExportEntity tableEntity = new ExcelExportEntity(head.getTableTxt(), subTable);
		tableEntity.setList(convertToExportEntity(fieldList,"id"));
		entityList.add(tableEntity);
		// 对字段列按顺序排序
		for (int i = 0; i < result.size(); i++) {
			params.put(linkField, result.get(i).get(mainField));
			String sql = CgformUtil.getQueryListDataCondition(head.getTableName(),fieldList, params);
			log.info("-----------动态列表查询子表sql》》"+sql);
			List<Map<String,Object>> subResult = this.onlCgformHeadService.queryListData(sql);
			// 转换器转换
			ConvertUtil.doConvertDataList(ConvertUtil.out,subResult,fieldList);
			//为了兼容各种数据库，将key统一转为小写
			result.get(i).put(subTable,CgformUtil.toLowerCasePageList(subResult));
		}
	}

	/**
	 * 校验数据库表名是否存在 若重复返回-1
	 * @param tbname
	 * @param id
	 * @return
	 */
	@GetMapping(value="/checkOnlyTable")
	public Result<?> checkOnlyTable(@RequestParam("tbname") String tbname,@RequestParam("id") String id){
		if(oConvertUtils.isEmpty(id)) {
			if(DbTableUtil.judgeTableIsExit(tbname)) {
				return Result.ok(-1);
			}
		}else {
			OnlCgformHead head = this.onlCgformHeadService.getById(id);
			if(!tbname.equals(head.getTableName())) {
				if(DbTableUtil.judgeTableIsExit(tbname)) {
					return Result.ok(-1);
				}
			}
		}
		return Result.ok(1);
	}

	/**
	 * 代码生成请求
	 */
	@PostMapping(value="/codeGenerate")
	public Result<?> codeGenerate(@RequestBody JSONObject json){
		OnlGenerateModel model = JSONObject.parseObject(json.toJSONString(), OnlGenerateModel.class);
		//生成文件日志
		List<String> generateFileList = null;
		try {
			if("1".equals(model.getJformType())) {
				//单表
				generateFileList = this.onlCgformHeadService.generateCode(model);
			}else {
				//主子表
				generateFileList = this.onlCgformHeadService.generateOneToMany(model);
			}
			return Result.ok(generateFileList);
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error(e.getMessage());
		}
	}

	/**
	 * 下载生成的代码
	 */
	@GetMapping(value = "/downGenerateCode")
	public void downGenerateCode(@RequestParam(value = "fileList") List<String> fileList, HttpServletRequest request, HttpServletResponse response) {
		//校验下载文件格式
		List<String> warningList = fileList.stream().filter(s -> s.indexOf("src/main/java") == -1 && s.indexOf("src%5Cmain%5Cjava") == -1).collect(Collectors.toList());
		if (fileList == null || (warningList != null && warningList.size() > 0)) {
			log.error(" fileList 不合法！！！", fileList);
			return;
		}
		String zipName = "生成代码_" + System.currentTimeMillis() + ".zip";
		String zipPathName = "/opt/temp/codegenerate/" + zipName;
		File file = GenerateCodeFileToZip.toZip(fileList, zipPathName);

		if (file.exists()) {
			response.setContentType("application/force-download");// 设置强制下载不打开
			response.addHeader("Content-Disposition", "attachment;fileName=" + zipName);// 设置文件名
			byte[] buffer = new byte[1024];
			FileInputStream fis = null;
			BufferedInputStream bis = null;
			try {
				fis = new FileInputStream(file);
				bis = new BufferedInputStream(fis);
				OutputStream os = response.getOutputStream();
				int i = bis.read(buffer);
				while (i != -1) {
					os.write(buffer, 0, i);
					i = bis.read(buffer);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (bis != null) {
					try {
						bis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				//延迟删除文件
				new Thread() {
					public void run() {
						try {
							Thread.sleep(10000);
							//删除压缩zip包
							FileUtil.del(zipPathName);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}.start();
			}
		}
	}

	/*----------------------------------树形列表-BEGIN-------------------------------------*/
	@GetMapping(value = "/getTreeData/{code}")
	@PermissionData
	public Result<Map<String,Object>> getTreeData(@PathVariable("code") String code,HttpServletRequest request) {
		Result<Map<String,Object>> result = new Result<>();
		OnlCgformHead head = onlCgformHeadService.getById(code);
		if (head == null) {
			result.error500("实体不存在");
			return result;
		}
		try {
			String tbname = head.getTableName();
			String hasChildrenField = head.getTreeIdField();
			String pidField = head.getTreeParentIdField();
			//树结构参数
			List<String> needList = Lists.newArrayList(hasChildrenField,pidField);
			Map<String,Object> params = CgformUtil.getParameterMap(request);

			String hasChildValue = null;
			if(params.get(hasChildrenField)!=null){
				hasChildValue = params.get(hasChildrenField).toString();
			}
			if(params.get(pidField)==null || "0".equals(params.get(pidField))) {
				//如果查询根节点 则支持分页
				params.put(pidField, "0");
			}else {
				//如果查询子节点,直接不走分页逻辑
				params.put("pageSize", -521);
				params.put(pidField, params.get(pidField));
			}
			params.put(hasChildrenField,null);
			Map<String,Object> page = onlCgformFieldService.queryAutolistPage(tbname, code, params,needList);

			//update-begin-author:taoyan date:20200416 for:如果没有子节点 需要改变状态
			if(params.get(pidField)!=null ){
				String pid = params.get(pidField).toString();
				if(!"0".equals(params.get(pidField))){
					//不是根节点 需要做如下处理
					if(page.get("total")!=null && Integer.parseInt(page.get("total").toString())==0){
						//如果没有查询出子节点  判断需不需要更新 父节点的状态
						if(hasChildValue!=null && "1".equals(hasChildValue)){
							//如果当前节点原本有子节点 现在木有了，更新状态
							onlCgformFieldService.updateTreeNodeNoChild(tbname,hasChildrenField,pid);
						}
					}
				}
			}
			//update-end-author:taoyan date:20200416 for:如果没有子节点 需要改变状态
			dataReprocessing(head,page);
			result.setResult(page);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			result.error500("数据库查询失败"+e.getMessage());
		}
		return result;
	}

	/**
	 * 数据再处理
	 * @param head
	 * @param page
	 * @throws BusinessException
	 */
	private void dataReprocessing (OnlCgformHead head,Map<String,Object> page) throws BusinessException {
		List<Map<String, Object>> dataList = (List<Map<String, Object>>)page.get("records");
		this.onlCgformHeadService.executeEnhanceList(head,CgformUtil.ENHANCE_QUERY,dataList);
	}


	/*----------------------------------树形列表-END-------------------------------------*/



	/*------------------------表单设计器专用---------------------------*/
	/**新增*/
	@PostMapping(value = "/crazyForm/{name}")
	public Result<?> formAddForDesigner(@PathVariable("name") String tableName,@RequestBody JSONObject jsonObject) {
		Result<String> result = new Result<String>();
		try {
			String uuid = CgformUtil.randomId();
			jsonObject.put("id", uuid);
			this.onlCgformHeadService.addCrazyFormData(tableName, jsonObject);
			result.setResult(uuid);
			result.setMessage("保存成功");
		} catch (Exception e) {
			log.error("OnlCgformApiController.formAddForDesigner()发生异常：" + e.getMessage(),e);
			return Result.error("保存失败");
		}
		return result;
	}

	/**编辑*/
	@PutMapping(value = "/crazyForm/{name}")
	public Result<?> formEditForDesigner(@PathVariable("name") String tableName,@RequestBody JSONObject jsonObject) {
		try {
			this.onlCgformHeadService.editCrazyFormData(tableName, jsonObject);
		} catch (Exception e) {
			log.error("OnlCgformApiController.formEditForDesigner()发生异常：" + e.getMessage(),e);
			return Result.error("保存失败");
		}
		return Result.ok("保存成功!");
	}
	/*------------------------表单设计器专用---------------------------*/



    /*----------------------------------ERP布局-----------------------------------------*/
    @GetMapping(value = "/getErpColumns/{code}")
    public Result<Map<String,Object>> getErpColumns(@PathVariable("code") String code) {
        Result<Map<String,Object>> result = new Result<>();
        OnlCgformHead head = onlCgformHeadService.getById(code);
        if (head == null) {
            result.error500("实体不存在");
            return result;
        }
        Map<String,Object> map = new HashMap<String,Object>();
        OnlComplexModel main = this.onlineService.queryOnlineConfig(head);
        map.put("main",main);
        if(CgformUtil.ONL_TYPE_ERP.equals(head.getThemeTemplate()) && head.getTableType()==2){
            //主表 且为erp风格配置
            String subStr = head.getSubTableStr();
            if(oConvertUtils.isNotEmpty(subStr)) {
                List<OnlComplexModel> list = new ArrayList<OnlComplexModel>();
                for (String tbname : subStr.split(",")) {
                    OnlCgformHead tempTable = this.onlCgformHeadService.getOne(new LambdaQueryWrapper<OnlCgformHead>().eq(OnlCgformHead::getTableName, tbname));
                    if(tempTable==null) {
                        continue;
                    }
                    list.add(this.onlineService.queryOnlineConfig(tempTable));
                }
                if(list.size()>0){
                    map.put("subList",list);
                }
            }
        }
        result.setResult(map);
        result.setSuccess(true);
        return result;
    }

	/**
	 * 查询表单结构数据
	 * @param code
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@GetMapping(value = "/getErpFormItem/{code}")
	public Result<?> getErpFormItem(@PathVariable("code") String code,HttpServletRequest request) {
		OnlCgformHead head = this.onlCgformHeadService.getById(code);
		if(head==null) {
			Result.error("表不存在");
		}
		Result<JSONObject> result = new Result<>();
		JSONObject obj = this.onlineService.queryOnlineFormObj(head);
		result.setResult(obj);
		return result;
	}

	/**
	 * 查询online级联下拉的数据项
	 * @return
	 */
	@GetMapping(value = "/querySelectOptions")
	public Result<List<TreeModel>> querySelectOptions(@ModelAttribute LinkDown linkDown) {
		Result<List<TreeModel>> result = new Result<List<TreeModel>>();
		List<TreeModel> list = this.onlCgformFieldService.queryDataListByLinkDown(linkDown);
		result.setResult(list);
		result.setSuccess(true);
		return result;
	}



}
